home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / tools / gcc / libnixv1_0.lha / gnu / libnix-sources.lha / sources / misc / swapstack.c < prev   
Encoding:
C/C++ Source or Header  |  1995-01-22  |  2.3 KB  |  103 lines

  1. #include <exec/memory.h>
  2. #include <dos/dosextens.h>
  3. #include <proto/exec.h>
  4. #include <proto/dos.h>
  5. #include "stabs.h"
  6. #include <stdlib.h>
  7.  
  8. /*
  9.  * swapstack.c
  10.  *
  11.  * A libnix startup module to swap to a new stack if the old one is not
  12.  * big enough (minimum value set by the value of the __stack variable).
  13.  *
  14.  * WARNING!
  15.  * Compile with -O3, or your Amiga will explode!
  16.  *
  17.  * Code derived from a stackswap module by Kriton Kyrimis (kyrimis@theseas.ntua.gr)
  18.  * with some changes to work with the libnix startups (MF).
  19.  * You use it at your own risk.
  20.  *
  21.  * Usage: Define some variable 'unsigned long __stack={desired size};'
  22.  *        somewhere in your code and link with this module.
  23.  *        The file stabs.h is in the headers directory of the libnix sources.
  24.  */
  25.  
  26. extern unsigned long __stack;
  27. void __request(const char *text);
  28.  
  29. static struct StackSwapStruct stack;
  30. static char *newstack;
  31.  
  32. void __stkinit(long a)
  33. {
  34.   register char *sp asm("sp");
  35.   ULONG size,needed=__stack;
  36.   struct Process *pr;
  37.   char *new;
  38.  
  39.   /* Determine original stack size */
  40.  
  41.   pr=(struct Process *)FindTask(NULL);
  42.  
  43.   size = (char *)pr->pr_Task.tc_SPUpper - (char *)pr->pr_Task.tc_SPLower;
  44.  
  45.   if (pr->pr_CLI)
  46.   {
  47.     size = *(ULONG *)pr->pr_ReturnAddr;
  48.   }
  49.  
  50.   if (needed <= size)
  51.     return;
  52.  
  53.   /* Round size to next long word */
  54.   needed = (needed+(sizeof(LONG)-1))&~(sizeof(LONG)-1);
  55.  
  56.   /* Allocate new stack */
  57.   newstack = new = AllocVec(needed,MEMF_PUBLIC);
  58.   if (!new)
  59.   {
  60.     __request("Couldn't allocate new stack!");
  61.     exit(RETURN_FAIL);
  62.   }
  63.  
  64.   /* Build new stack structure */
  65.   size=(char *)&a-sp+2*sizeof(ULONG);
  66.   stack.stk_Lower  =new;
  67.   stack.stk_Upper  =(ULONG)(new+=needed);
  68.   stack.stk_Pointer=(APTR)(new-=size);
  69.  
  70.   /* Copy required parts of old stack */
  71.   CopyMem(sp,new,size);
  72.  
  73.   /* Switch to new stack */
  74.   StackSwap(&stack);
  75. }
  76.  
  77. void __stkexit(ULONG a)
  78. {
  79.   register char *sp asm("sp");
  80.   ULONG size;
  81.   char *new;
  82.  
  83.   if(!(new=newstack))
  84.     return;
  85.  
  86.   /* Prepare old stack */
  87.   size=(char *)&a-sp+3*sizeof(ULONG);
  88.   stack.stk_Pointer=(APTR)((char *)stack.stk_Pointer-size);
  89.  
  90.   /* Copy required parts of current stack */
  91.   CopyMem(sp,stack.stk_Pointer,size);
  92.  
  93.   /* Switch back to old stack */
  94.   StackSwap(&stack);
  95.  
  96.   /* And clean up */
  97.   FreeVec(new);
  98. }
  99.  
  100. /* The same priority as the detach module - you cannot use them both */
  101. ADD2INIT(__stkinit,-70);
  102. ADD2EXIT(__stkexit,-70);
  103.